﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Xml.XPath;
namespace GCELibrary.Current
{
    /// <summary>
    /// 搜索范围
    /// </summary>
    public enum XmlRange
    {
        All,//所有节点
        Root,//根节点
        ThisNode,//当前节点
    }
    /// <summary>
    /// xml查询模块
    /// </summary>
    public static class XmlHelper
    {
        /// <summary>
        /// 生成xpath路径
        /// </summary>
        /// <param name="xeName">节点名称</param>
        /// <param name="xeAttribute">节点属性</param>
        /// <param name="xeValue">属性值</param>
        /// <param name="e">范围</param>
        /// <returns></returns>
        public static string GetXPath(string xeName, string xeAttribute, string xeValue, XmlRange range)
        {
            string XPath = null;
            switch (range)
            {
                case XmlRange.All:
                    if (xeAttribute != null && xeValue != null && xeAttribute.Trim() != "" && xeValue.Trim() != "")
                        XPath = string.Format("//{0}[@{1}=\"{2}\"]", xeName, xeAttribute, xeValue);
                    else
                        XPath = "//" + xeName;
                    break;
                case XmlRange.Root:
                    if (xeAttribute != null && xeValue != null && xeAttribute.Trim() != "" && xeValue.Trim() != "")
                        XPath = string.Format("/{0}[@{1}=\"{2}\"]", xeName, xeAttribute, xeValue);
                    else
                        XPath = "/" + xeName;
                    break;
                case XmlRange.ThisNode:
                    if (xeAttribute != null && xeValue != null && xeAttribute.Trim() != "" && xeValue.Trim() != "")
                        XPath = string.Format("{0}[@{1}=\"{2}\"]", xeName, xeAttribute, xeValue);
                    else
                        XPath = "" + xeName;
                    break;
            }
            return XPath;
        }
        /// <summary>
        /// 获取第一个附合条件的节点元素
        /// </summary>
        /// <param name="strXML">被搜索的字符串格式的xml</param>
        /// <param name="XPath">路径</param>
        /// <returns></returns>
        public static XmlElement GetFirstXmlElement(string strXML, string xPath)
        {
            bool ok = false;
            XmlDocument xDoc = new XmlDocument();
            try
            {
                xDoc.LoadXml(strXML);
                ok = true;
            }
            catch (Exception ex)
            {
                throw new ArgumentException("Xml字符串格式错误", "strXML");
            }
            if (ok)
                return GetFirstXmlElement(xDoc, xPath);
            else
                return null;
        }
        /// <summary>
        /// 获取第一个附合条件的节点元素
        /// </summary>
        /// <param name="xElement">被搜索的元素节点</param>
        /// <param name="Name">节点名称</param>
        /// <param name="e">范围</param>
        /// <returns></returns>
        public static XmlElement GetFirstXmlElement(XmlElement xElement, string name, XmlRange range)
        {
            XmlDocument xDoc = new XmlDocument();
            xDoc.LoadXml(xElement.OuterXml);
            return GetFirstXmlElement(xDoc, name, range);
        }
        /// <summary>
        /// 获取第一个附合条件的节点元素
        /// </summary>
        /// <param name="xElement">被搜索的元素节点</param>
        /// <param name="XPath">路径</param>
        /// <returns></returns>
        public static XmlElement GetFirstXmlElement(XmlElement xElement, string xPath)
        {
            XmlDocument xDoc = new XmlDocument();
            xDoc.LoadXml(xElement.OuterXml);
            return GetFirstXmlElement(xDoc, xPath);
        }
        /// <summary>
        /// 获取第一个附合条件的节点元素
        /// </summary>
        /// <param name="xDoc">XML文档</param>
        /// <param name="Name">节点名称</param>
        /// <param name="e">范围</param>
        /// <returns></returns>
        public static XmlElement GetFirstXmlElement(XmlDocument xDoc, string name, XmlRange range)
        {
            string XPath = GetXPath(name, null, null, range);
            return GetFirstXmlElement(xDoc, XPath);
        }
        /// <summary>
        /// 获取第一个附合条件的节点元素
        /// </summary>
        /// <param name="xDoc">XML文档</param>
        /// <param name="XPath">路径</param>
        /// <returns></returns>
        public static XmlElement GetFirstXmlElement(XmlDocument xDoc, string xPath)
        {
            XmlNode xn = xDoc.DocumentElement.SelectSingleNode(xPath);
            return (XmlElement)xn;
        }
        /// <summary>
        /// 获取第一个附合条件的节点元素
        /// </summary>
        /// <param name="xDoc">XML文档</param>
        /// <param name="Name">节点名称</param>
        /// <param name="Attribute">属性名称</param>
        /// <param name="Value">属性值</param>
        /// <param name="e">范围</param>
        /// <returns></returns>
        public static XmlElement GetFirstXmlElement(XmlDocument xDoc, string name, string attribute, string value, XmlRange range)
        {
            string XPath = GetXPath(name, attribute, value, range);
            return GetFirstXmlElement(xDoc, XPath);
        }
        /// <summary>
        /// 获取第一个附合条件的节点元素
        /// </summary>
        /// <param name="xDoc">XML文档</param>
        /// <param name="Name">节点名称</param>
        /// <param name="Attribute">属性名称</param>
        /// <param name="Value">属性值</param>
        /// <returns></returns>
        public static XmlElement GetFirstXmlElement(XmlDocument xDoc, string name, string attribute, string value)
        {
            string XPath = GetXPath(name, attribute, value, XmlRange.ThisNode);
            return GetFirstXmlElement(xDoc, XPath);
        }
        /// <summary>
        /// 获取符合条件的节点集
        /// </summary>
        /// <param name="xDoc">XML文档</param>
        /// <param name="Name">节点名称</param>
        /// <param name="e">范围</param>
        /// <returns></returns>
        public static XmlNodeList GetXmlNodeList(XmlDocument xDoc, string name, XmlRange range)
        {
            string XPath = GetXPath(name, null, null, range);
            return GetXmlNodeList(xDoc, XPath);
        }
        /// <summary>
        /// 获取符合条件的节点集
        /// </summary>
        /// <param name="xDoc">XML文档</param>
        /// <param name="Name">节点名称</param>
        /// <param name="Attribute">节点属性</param>
        /// <param name="Value">属性值</param>
        /// <returns></returns>
        public static XmlNodeList GetXmlNodeList(XmlDocument xDoc, string name, string attribute, string value)
        {
            string XPath = GetXPath(name, attribute, value, XmlRange.ThisNode);
            return GetXmlNodeList(xDoc, XPath);
        }
        /// <summary>
        /// 获取符合条件的节点集
        /// </summary>
        /// <param name="xDoc">XML文档</param>
        /// <param name="Name">节点名称</param>
        /// <param name="Attribute">节点属性</param>
        /// <param name="Value">属性值</param>
        /// <param name="e">范围</param>
        /// <returns></returns>
        public static XmlNodeList GetXmlNodeList(XmlDocument xDoc, string name, string attribute, string value, XmlRange range)
        {
            string XPath = GetXPath(name, attribute, value, range);
            return GetXmlNodeList(xDoc, XPath);
        }
        /// <summary>
        ///获取符合条件的节点集
        /// </summary>
        /// <param name="xDoc">XML文档</param>
        /// <param name="XPath">路径</param>
        /// <returns></returns>
        public static XmlNodeList GetXmlNodeList(XmlDocument xDoc, string xPath)
        {
            return xDoc.DocumentElement.SelectNodes(xPath);
        }
        /// <summary>
        /// 获取元素节点
        /// </summary>
        /// <param name="xDoc">XElement节点</param>
        /// <param name="Name">节点名称</param>
        /// <param name="e">范围</param>
        /// <returns></returns>
        public static XElement GetFirstXElement(XElement xElement, string name, XmlRange range)
        {
            string XPath = GetXPath(name, null, null, range);
            return GetFirstXElement(xElement, XPath);
        }
        /// <summary>
        /// 获取元素节点
        /// </summary>
        /// <param name="xDoc">XElement节点</param>
        /// <param name="XPath">路径</param>
        /// <returns></returns>
        public static XElement GetFirstXElement(XElement xElement, string xPath)
        {

            return xElement.XPathSelectElement(xPath);
        }
        /// <summary>
        /// 获取元素节点
        /// </summary>
        /// <param name="xDoc">XElement节点</param>
        /// <param name="Name">节点名称</param>
        /// <param name="Attribute">节点属性名称</param>
        /// <param name="Value">节点属性值</param>
        /// <param name="e">范围</param>
        /// <returns></returns>
        public static XElement GetFirstXElement(XElement xElement, string name, string attribute, string value, XmlRange range)
        {
            string XPath = GetXPath(name, null, null, range);
            return GetFirstXElement(xElement, XPath);
        }
        /// <summary>
        /// 获取元素节点集
        /// </summary>
        /// <param name="xDoc">XElement节点</param>
        /// <param name="Name">节点名称</param>
        /// <param name="e">范围</param>
        /// <returns></returns>
        public static IEnumerable<XElement> GetXElement(XElement xElement, string name, XmlRange range)
        {
            string XPath = GetXPath(name, null, null, range);
            return GetXElement(xElement, XPath);
        }
        /// <summary>
        /// 获取元素节点集
        /// </summary>
        /// <param name="xDoc">XElement节点</param>
        /// <param name="XPath">路径</param>
        /// <returns></returns>
        public static IEnumerable<XElement> GetXElement(XElement xElement, string xPath)
        {
            return xElement.XPathSelectElements(xPath);
        }
        /// <summary>
        /// 获取元素节点集
        /// </summary>
        /// <param name="xDoc">XElement节点</param>
        /// <param name="Name">节点名称</param>
        /// <param name="Attribute">节点属性名称</param>
        /// <param name="Value">节点属性值</param>
        /// <param name="e">范围</param>
        /// <returns></returns>
        public static IEnumerable<XElement> GetXElement(XElement xElement, string name, string attribute, string value, XmlRange range)
        {
            string XPath = GetXPath(name, null, null, range);
            return GetXElement(xElement, XPath);
        }
        /// <summary>
        /// 获取元素节点
        /// </summary>
        /// <param name="xDoc">XDocment文档</param>
        /// <param name="Name">节点名称</param>
        /// <param name="e">范围</param>
        /// <returns></returns>
        public static XElement GetFirstXElement(XDocument xDoc, string name, XmlRange range)
        {
            string XPath = GetXPath(name, null, null, range);
            return xDoc.Root.XPathSelectElement(XPath);
        }
        /// <summary>
        /// 获取元素节点
        /// </summary>
        /// <param name="xDoc">XDocment文档</param>
        /// <param name="XPath">路径</param>
        /// <returns></returns>
        public static XElement GetFirstXElement(XDocument xDoc, string xPath)
        {
            return xDoc.Root.XPathSelectElement(xPath);
        }
        /// <summary>
        /// 获取元素节点
        /// </summary>
        /// <param name="xDoc">XDocment文档</param>
        /// <param name="Name">节点名称</param>
        /// <param name="Attribute">节点属性名称</param>
        /// <param name="Value">节点属性值</param>
        /// <param name="e">范围</param>
        /// <returns></returns>
        public static XElement GetFirstXElement(XDocument xDoc, string name, string attribute, string value, XmlRange range)
        {
            string XPath = GetXPath(name, null, null, range);
            return xDoc.Root.XPathSelectElement(XPath);
        }
        /// <summary>
        /// 获取元素节点集
        /// </summary>
        /// <param name="xDoc">XDocment文档</param>
        /// <param name="Name">节点名称</param>
        /// <param name="e">范围</param>
        /// <returns></returns>
        public static IEnumerable<XElement> GetXElement(XDocument xDoc, string name, XmlRange range)
        {
            string XPath = GetXPath(name, null, null, range);
            return xDoc.Root.XPathSelectElements(XPath);
        }
        /// <summary>
        /// 获取元素节点集
        /// </summary>
        /// <param name="xDoc">XDocment文档</param>
        /// <param name="XPath">路径</param>
        /// <returns></returns>
        public static IEnumerable<XElement> GetXElement(XDocument xDoc, string xPath)
        {
            return xDoc.Root.XPathSelectElements(xPath);
        }
        /// <summary>
        /// 获取元素节点集
        /// </summary>
        /// <param name="xDoc">XDocment文档</param>
        /// <param name="Name">节点名称</param>
        /// <param name="Attribute">节点属性名称</param>
        /// <param name="Value">节点属性值</param>
        /// <param name="e">范围</param>
        /// <returns></returns>
        public static IEnumerable<XElement> GetXElement(XDocument xDoc, string name, string attribute, string value, XmlRange range)
        {
            string XPath = GetXPath(name, null, null, range);
            return xDoc.Root.XPathSelectElements(XPath);
        }

    }
}
